﻿namespace Marc.JwOrgClient.Model {
    using System;
    using System.Collections.ObjectModel;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Xml.Linq;

    public class Podcast {
        private readonly Language _language;
        private readonly MagazineType _magazineType;
        private readonly ObservableCollection<PodcastMagazine> _magazines = new ObservableCollection<PodcastMagazine>();

        public Podcast(Language language, MagazineType magazineType) {
            this._language = language;
            this._magazineType = magazineType;
        }

        public MagazineType MagazineType {
            get { return this._magazineType; }
        }

        public Language Language {
            get { return this._language; }
        }

        public ObservableCollection<PodcastMagazine> Magazines {
            get { return this._magazines; }
        }

        private Uri BuildFeedUrl() {
            const string PODCAST_URL_TEMPLATE = "http://www.jw.org/apps/index.xjp?option=sFFZRQVNZNT&rln={0}&rmn={1}&rfm=mp3";
            return new Uri(string.Format(PODCAST_URL_TEMPLATE, this.Language.Key, this.MagazineType.DownloadKey));
        }

        public void DownloadMetadata(Action downloadCompleteCallback) {
            this.Magazines.Clear();

            WebRequest request = WebRequest.Create(this.BuildFeedUrl());
            request.BeginGetResponse(
                ar => {
                    if (ar.IsCompleted) {
                        using (WebResponse response = request.EndGetResponse(ar)) {
                            using (Stream responseStream = response.GetResponseStream()) {
                                XDocument feedXML = XDocument.Load(responseStream);
                                var magazines = feedXML.Descendants("item")
                                                       .Select(it => new {
                                                           title = it.Element("title").Value,
                                                           description = it.Element("description").Value,
                                                           link = new Uri(it.Element("link").Value),
                                                           guid = it.Element("guid").Value,
                                                           pubDate = DateTime.Parse(it.Element("pubDate").Value), //, "ddd, dd MMM yyyy hh:mm:ss GMT"
                                                       }).GroupBy(at => at.pubDate);
                                foreach (var magazine in magazines) {
                                    this.Magazines.Add(
                                        new PodcastMagazine(this.Language,
                                                            this.MagazineType,
                                                            magazine.Key,
                                                            magazine.OrderBy(ch => ch.pubDate)
                                                                    .Select((ch, i) => new PodcastMagazineChapter(i, ch.title, ch.description, ch.link, 0, ch.guid))
                                                                    .ToArray()))
                                        ;
                                }

                                downloadCompleteCallback();
                            }
                        }
                    }
                }, null);
        }
    }
}